//
//  WHBaseScanController.m
//  BinFengExpressOwner
//
//  Created by 邓伟浩 on 2018/10/19.
//  Copyright © 2018年 BinFeng. All rights reserved.
//

#import "WHBaseScanController.h"


@interface WHBaseScanController ()<AVCaptureMetadataOutputObjectsDelegate, AVCaptureVideoDataOutputSampleBufferDelegate>

@property (nonatomic, strong) AVCaptureSession *session;
@property (nonatomic, strong) UIImageView *lineImageView;
@property (nonatomic, strong) UIImageView *centerImageView;

@property (nonatomic, strong) UIButton *openLightBtn;


@end

@interface WHBaseScanController ()

@end

@implementation WHBaseScanController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        
        if (status == AVAuthorizationStatusRestricted || status == AVAuthorizationStatusDenied) {
            [WHView showAlertwithTitle:@"用户拒绝授权" message:@"请去-> [设置 - 隐私 - 相机 - 松鼠侠] 打开相机访问权限" okTitle:@"去设置" okAction:^(UIAlertAction *action) {
                NSURL *settingURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                if ([[UIApplication sharedApplication] canOpenURL:settingURL]) {
                    [[UIApplication sharedApplication] openURL:settingURL];
                }
            } cacelTitle:@"取消" cancelAction:^(UIAlertAction *action) {
                [self dismissViewControllerAnimated:YES completion:nil];
            }];
        } else {
            _isVideoAvalible = YES;
            [self loadScanView];
        }
    } else {
        DLog(@"不支持摄像机");
        [WHView showAlertwithTitle:nil message:@"不支持摄像机"];
    }
}

- (void)loadScanView {
    // 获取摄像设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    // 创建输入流
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
    // 创建输出流
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc]init];
    // 设置代理 在主线程里刷新
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    AVCaptureVideoDataOutput *lightOutput = [[AVCaptureVideoDataOutput alloc] init];
    [lightOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
    
    // 初始化链接对象
    self.session = [[AVCaptureSession alloc] init];
    // 高质量采集率
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
    
    if (input) {
        [self.session addInput:input];
    }
    if (output) {
        [self.session addOutput:output];
        [self.session addOutput:lightOutput];
        // 设置扫码支持的编码格式(如下设置条形码和二维码兼容)
        output.metadataObjectTypes = @[// 以下条形码
                                       AVMetadataObjectTypeEAN13Code,
                                       AVMetadataObjectTypeEAN8Code,
                                       AVMetadataObjectTypeUPCECode,
                                       AVMetadataObjectTypeCode39Code,
                                       AVMetadataObjectTypeCode39Mod43Code,
                                       AVMetadataObjectTypeCode93Code,
                                       AVMetadataObjectTypeCode128Code,
                                       AVMetadataObjectTypePDF417Code];
    }
    
    
    AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    layer.frame = self.view.layer.bounds;
    [self.view.layer insertSublayer:layer atIndex:0];
    [self setOverlayPickerView];
    
//    [self.session addObserver:self forKeyPath:@"running" options:NSKeyValueObservingOptionNew context:nil];
    
    //开始捕获
//    [self.session startRunning];
    
}

- (void)setOverlayPickerView {
    UIImageView *centerView = [[UIImageView alloc] init];
    centerView.center = self.view.center;
    centerView.image = IMAGE_NAMED(@"scan_circle");
    centerView.contentMode = UIViewContentModeScaleAspectFit;
    [self.view addSubview:centerView];
    _centerImageView = centerView;
    
    [centerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.height.mas_equalTo(kRealwidth(260));
        make.center.mas_equalTo(self.view);
    }];
    [self.view layoutIfNeeded];
    
    // 最外层套一个大的矩形
    UIBezierPath *bpath = [UIBezierPath bezierPathWithRect:CGRectMake(-5, -5, _centerImageView.width + 10, _centerImageView.height + 10)];
    // 中间添加一个矩形
    [bpath appendPath:[[UIBezierPath bezierPathWithRect:CGRectMake(0, 0, _centerImageView.width, _centerImageView.height)] bezierPathByReversingPath]];
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = bpath.CGPath;
    shapeLayer.fillColor = HexColor(@"c2c2c2").CGColor;
    //    shapeLayer.strokeColor = [UIColor redColor].CGColor;
    
    [_centerImageView.layer addSublayer:shapeLayer];
    
    UIColor *backColor = KBlackColor;
    
    // 左侧的view
    UIImageView *leftView = [[UIImageView alloc] init];
    leftView.alpha = 0.4;
    leftView.backgroundColor = backColor;
    [self.view addSubview:leftView];
    [leftView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.bottom.mas_equalTo(self.view);
        make.right.mas_equalTo(_centerImageView.mas_left);
    }];
    
    // 右侧的view
    UIImageView *rightView = [[UIImageView alloc] init];
    rightView.alpha = 0.4;
    rightView.backgroundColor = backColor;
    [self.view addSubview:rightView];
    [rightView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.right.bottom.mas_equalTo(self.view);
        make.left.mas_equalTo(_centerImageView.mas_right);
    }];
    
    // 最上部view
    UIImageView *topView = [[UIImageView alloc] init];
    topView.alpha = 0.4;
    topView.backgroundColor = backColor;
    [self.view addSubview:topView];
    [topView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.view.mas_top);
        make.left.mas_equalTo(leftView.mas_right);
        make.right.mas_equalTo(rightView.mas_left);
        make.bottom.mas_equalTo(_centerImageView.mas_top);
    }];
    
    // 底部view
    UIImageView *bottomView = [[UIImageView alloc] init];
    bottomView.alpha = 0.4;
    bottomView.backgroundColor = backColor;
    [self.view addSubview:bottomView];
    [bottomView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.mas_equalTo(self.view);
        make.left.mas_equalTo(leftView.mas_right);
        make.right.mas_equalTo(rightView.mas_left);
        make.top.mas_equalTo(_centerImageView.mas_bottom);
    }];
    
    [self.view layoutIfNeeded];
    
    UIImageView *lineImageView = [[UIImageView alloc] init];
    lineImageView.image = IMAGE_NAMED(@"scan_line");
    lineImageView.frame = CGRectMake(_centerImageView.left, _centerImageView.top, _centerImageView.width, 2);
    lineImageView.contentMode = UIViewContentModeScaleAspectFill;
    [self.view addSubview:lineImageView];
    _lineImageView = lineImageView;
    
    
    UILabel *tipsLabel = [[UILabel alloc] init];
    tipsLabel.textColor = KWhiteColor;
    tipsLabel.textAlignment = NSTextAlignmentCenter;
    tipsLabel.font = SYSTEMFONT(15);
    tipsLabel.text = @"将条码放入框内,即可自动扫描";
    [self.view addSubview:tipsLabel];
    
    [tipsLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.mas_equalTo(kRealwidth(15));
        make.centerX.mas_equalTo(self.view.mas_centerX);
        make.bottom.mas_equalTo(_centerImageView.mas_top).offset(-kRealwidth(40));
    }];
    
    UIButton *openLightBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [openLightBtn setImage:IMAGE_NAMED(@"scan_open") forState:UIControlStateNormal];
    [openLightBtn setImage:IMAGE_NAMED(@"scan_close") forState:UIControlStateSelected];
    [self.view addSubview:openLightBtn];
    [openLightBtn addTarget:self action:@selector(clickLightBtn:) forControlEvents:UIControlEventTouchUpInside];
    [openLightBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.width.mas_equalTo(kRealwidth(40));
        make.centerX.mas_equalTo(self.view.mas_centerX);
        make.bottom.mas_equalTo(_centerImageView.mas_bottom).offset(-kRealwidth(40));
    }];
    _openLightBtn = openLightBtn;
    _openLightBtn.selected = NO;
//    _openLightBtn.hidden = YES;
}

#pragma mark - —————— AVCaptureMetadataOutputObjectsDelegate ——————
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    
    if (metadataObjects.count > 0) {
        [self.session stopRunning];
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"scanSuccess.wav" withExtension:nil];
        // 加载音效文件，创建音效ID(SoundID,一个ID对应一个音效文件)
        SystemSoundID soundID = 8787;
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
        // 播放音效文件
        // 下面的两个函数都可以用来播放音效文件，第一个函数伴随有震动效果
        AudioServicesPlayAlertSound(soundID);
        //        AudioServicesPlaySystemSound(8787);
        
        AVMetadataMachineReadableCodeObject *metadataObject = metadataObjects[0];
        
        [self outPutReadableObject:metadataObject];
        
    }
}

- (void)outPutReadableObject:(AVMetadataMachineReadableCodeObject *)metadataObject {
//    //输出扫描字符串
//    NSString *dataStr = metadataObject.stringValue;
//    DLog(@"dataStr = %@", dataStr);
//
//    [self.navigationController popViewControllerAnimated:YES];
}

#pragma mark - —————— observe ——————
- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)context {
    if ([object isKindOfClass:[AVCaptureSession class]]) {
        BOOL isRunning = ((AVCaptureSession *)object).isRunning;
        if (isRunning) {
            [self addAnimation];
        } else {
            [self removeAnimation];
        }
    }
}

- (void)addAnimation {
    _lineImageView.hidden = NO;
    
    CABasicAnimation *animationMove = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    [animationMove setFromValue:[NSNumber numberWithFloat:0]];
    [animationMove setToValue:[NSNumber numberWithFloat:_centerImageView.height-2]];
    animationMove.duration = 2;
    animationMove.repeatCount  = OPEN_MAX;
    animationMove.fillMode = kCAFillModeForwards;
    animationMove.removedOnCompletion = NO;
    animationMove.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    
    [_lineImageView.layer addAnimation:animationMove forKey:@"LineAnimation"];
}

- (void)removeAnimation {
    [_lineImageView.layer removeAnimationForKey:@"LineAnimation"];
    _lineImageView.hidden = YES;
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.session removeObserver:self forKeyPath:@"running" context:nil];
    [self.session stopRunning];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.session addObserver:self forKeyPath:@"running" options:NSKeyValueObservingOptionNew context:nil];
    [self.session startRunning];
    
    UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
    backButton.frame = CGRectMake(0, 0, 40, kNavBarHeight);
    [backButton addTarget:self action:@selector(backBtnClicked) forControlEvents:UIControlEventTouchUpInside];
    [backButton setImage:IMAGE_NAMED(@"icon_menu_whiteBack") forState:UIControlStateNormal];
    UIBarButtonItem *back = [[UIBarButtonItem alloc] initWithCustomView:backButton];
    self.navigationItem.leftBarButtonItem = back;
}


- (void)clickLightBtn:(UIButton *)sender {
    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        
        if ([device hasTorch] && [device hasFlash]){
            [device lockForConfiguration:nil];
            if (device.torchMode == AVCaptureTorchModeOn) {
                [device setTorchMode:AVCaptureTorchModeOff];
                [device setFlashMode:AVCaptureFlashModeOff];
                sender.selected = NO;
            } else if (device.torchMode == AVCaptureTorchModeOff) {
                [device setTorchMode:AVCaptureTorchModeOn];
                [device setFlashMode:AVCaptureFlashModeOn];
                sender.selected = YES;
            }
            [device unlockForConfiguration];
        }
    }
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {

    Class captureDeviceClass = NSClassFromString(@"AVCaptureDevice");
    if (captureDeviceClass != nil) {
        CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
        NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
        CFRelease(metadataDict);
        NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
        float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
//        NSLog(@"当前亮度值: %f",brightnessValue);

        // 根据brightnessValue的值来打开和关闭闪光灯
        AVCaptureDevice * myLightDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        BOOL result = [myLightDevice hasTorch]; // 判断设备是否有闪光灯
        
        if (myLightDevice.torchMode == AVCaptureTorchModeOff) {
            if ((brightnessValue < -0.2) && result) { // 打开闪光灯
                [myLightDevice lockForConfiguration:nil];
                [myLightDevice setTorchMode:AVCaptureTorchModeOn];//开
                //            [myLightDevice setFlashMode:AVCaptureFlashModeOn];
                [myLightDevice unlockForConfiguration];
                _openLightBtn.hidden = NO;
                _openLightBtn.selected = YES;
            } else if((brightnessValue > 0) && result) {// 关闭闪光灯
                //            [myLightDevice lockForConfiguration:nil];
                //            [myLightDevice setTorchMode:AVCaptureTorchModeOff];
                //            [myLightDevice setFlashMode:AVCaptureFlashModeOff];
                //            [myLightDevice unlockForConfiguration];
                _openLightBtn.hidden = YES;
            }
        }
        }
}

@end
